<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>西安地铁路线绘制与最短路线计算</title>
    <style>
        /* 站点样式 */
        .station {
            width: 20px;
            height: 20px;
            background-color: #333;
            border-radius: 50%;
            position: absolute;
            cursor: pointer;
        }

        /* 线路样式 */
        .line {
            position: absolute;
            background-color: #999;
        }

        /* 高亮样式 */
        .highlight {
            background-color: red;
        }

        /* 站点名字样式 */
        .station-name {
            position: absolute;
            font-size: 12px;
            white-space: nowrap;
        }

        /* 容器样式 */
        #map-container {
            position: relative;
            width: 1200px;
            height: 1000px;
            border: 1px solid #ccc;
        }
    </style>
</head>

<body>
    <h1>西安地铁路线绘制与最短路线计算</h1>
    <label for="start">起点：</label>
    <input type="text" id="start">
    <label for="end">终点：</label>
    <input type="text" id="end">
    <button onclick="findShortestRoute()">查询</button>
    <div id="result"></div>
    <div id="map-container"></div>

    <script>
        // 西安部分地铁路线站点坐标数据（模拟）
        const stations = {
            "北大街": { x: 300, y: 200 },
            "钟楼": { x: 400, y: 200 },
            "小寨": { x: 400, y: 350 },
            "会展中心": { x: 400, y: 450 },
            "五路口": { x: 500, y: 200 },
            "纺织城": { x: 650, y: 200 },
            "通化门": { x: 550, y: 200 },
            "延平门": { x: 200, y: 200 },
            "鱼化寨": { x: 100, y: 200 },
            "市图书馆": { x: 300, y: 100 },
            "行政中心": { x: 300, y: 50 },
            "运动公园": { x: 300, y: 0 },
            "韦曲南": { x: 400, y: 550 },
            "航天城": { x: 400, y: 650 },
            // 8 号环线站点
            "堡子村": { x: 350, y: 150 },
            "浐灞中心": { x: 500, y: 150 },
            "雁翔路": { x: 500, y: 300 },
            "曲江池西": { x: 400, y: 300 },
            "电子城": { x: 300, y: 300 },
            "土门": { x: 200, y: 250 },
            "大白杨": { x: 250, y: 150 }
        };

        // 西安部分地铁路线信息（模拟）
        const allLines = [
            [["北大街", "钟楼"], ["钟楼", "小寨"], ["小寨", "会展中心"], ["会展中心", "韦曲南"], ["韦曲南", "航天城"]], // 2 号线
            [["钟楼", "五路口"], ["五路口", "通化门"], ["通化门", "纺织城"]], // 1 号线
            [["延平门", "北大街"], ["北大街", "市图书馆"], ["市图书馆", "行政中心"], ["行政中心", "运动公园"]], // 4 号线
            [["延平门", "钟楼"], ["钟楼", "五路口"]], // 模拟的新线路
            // 8 号环线
            [["堡子村", "浐灞中心"], ["浐灞中心", "雁翔路"], ["雁翔路", "曲江池西"], ["曲江池西", "电子城"], ["电子城", "土门"], ["土门", "大白杨"], ["大白杨", "堡子村"]]
        ];

        const mapContainer = document.getElementById('map-container');

        // 绘制站点及名字
        function drawStations() {
            for (const station in stations) {
                const { x, y } = stations[station];
                // 绘制站点
                const stationDiv = document.createElement('div');
                stationDiv.classList.add('station');
                stationDiv.style.left = `${x - 10}px`;
                stationDiv.style.top = `${y - 10}px`;
                stationDiv.id = station;
                mapContainer.appendChild(stationDiv);

                // 绘制站点名字
                const nameDiv = document.createElement('div');
                nameDiv.classList.add('station-name');
                nameDiv.textContent = station;
                nameDiv.style.left = `${x + 15}px`;
                nameDiv.style.top = `${y - 8}px`;
                mapContainer.appendChild(nameDiv);
            }
        }

        // 绘制所有线路
        function drawAllLines() {
            for (const lineSet of allLines) {
                for (const line of lineSet) {
                    const start = stations[line[0]];
                    const end = stations[line[1]];
                    const dx = end.x - start.x;
                    const dy = end.y - start.y;
                    const length = Math.sqrt(dx * dx + dy * dy);
                    const angle = Math.atan2(dy, dx) * (180 / Math.PI);

                    const lineDiv = document.createElement('div');
                    lineDiv.classList.add('line');
                    lineDiv.style.width = `${length}px`;
                    lineDiv.style.height = '2px';
                    lineDiv.style.left = `${start.x}px`;
                    lineDiv.style.top = `${start.y}px`;
                    lineDiv.style.transform = `rotate(${angle}deg)`;
                    lineDiv.style.transformOrigin = '0 0';
                    lineDiv.dataset.start = line[0];
                    lineDiv.dataset.end = line[1];
                    mapContainer.appendChild(lineDiv);
                }
            }
        }

        // 构建邻接表
        function buildGraph() {
            const graph = {};
            for (const lineSet of allLines) {
                for (const line of lineSet) {
                    const [start, end] = line;
                    if (!graph[start]) graph[start] = [];
                    if (!graph[end]) graph[end] = [];
                    graph[start].push(end);
                    graph[end].push(start);
                }
            }
            return graph;
        }

        // 广度优先搜索计算最短路线
        function bfs(graph, start, end) {
            const queue = [[start]];
            const visited = new Set();
            visited.add(start);

            while (queue.length > 0) {
                const path = queue.shift();
                const current = path[path.length - 1];

                if (current === end) {
                    return path;
                }

                const neighbors = graph[current] || [];
                for (const neighbor of neighbors) {
                    if (!visited.has(neighbor)) {
                        const newPath = [...path, neighbor];
                        queue.push(newPath);
                        visited.add(neighbor);
                    }
                }
            }

            return null;
        }

        // 查找最短路线并高亮显示
        function findShortestRoute() {
            const start = document.getElementById('start').value;
            const end = document.getElementById('end').value;
            const graph = buildGraph();
            const path = bfs(graph, start, end);

            if (path) {
                highlightPath(path);
                const resultText = `最短路线：${path.join(' -> ')}`;
                document.getElementById('result').textContent = resultText;
            } else {
                document.getElementById('result').textContent = '未找到合适的路线';
            }
        }

        // 高亮最短路线
        function highlightPath(path) {
            // 移除之前的高亮样式
            const allStations = document.querySelectorAll('.station');
            const allLines = document.querySelectorAll('.line');
            allStations.forEach(station => station.classList.remove('highlight'));
            allLines.forEach(line => line.classList.remove('highlight'));

            // 高亮站点
            path.forEach(station => {
                const stationDiv = document.getElementById(station);
                if (stationDiv) {
                    stationDiv.classList.add('highlight');
                }
            });

            // 高亮线路
            for (let i = 0; i < path.length - 1; i++) {
                const start = path[i];
                const end = path[i + 1];
                const lineDiv = Array.from(allLines).find(line =>
                    (line.dataset.start === start && line.dataset.end === end) ||
                    (line.dataset.start === end && line.dataset.end === start)
                );
                if (lineDiv) {
                    lineDiv.classList.add('highlight');
                }
            }
        }

        // 初始化绘制
        function init() {
            drawStations();
            drawAllLines();
        }

        init();
    </script>
</body>

</html>